// original Source by Code Project Articles/36495
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System.Windows;
using System.Windows.Media;

// ReSharper disable CheckNamespace
namespace DevPhone.Controls
// ReSharper restore CheckNamespace
{
    public static class ClipBoundsControl
    {
        public static bool GetToBounds(DependencyObject dependencyObject)
        {
            if (dependencyObject == null) return false;
            return (bool)dependencyObject.GetValue(ToBoundsProperty);
        }

        public static void SetToBounds(DependencyObject dependencyObject, bool clipToBounds)
        {
            if (dependencyObject != null)
            {
                dependencyObject.SetValue(ToBoundsProperty, clipToBounds);
            }
        }

        public static readonly DependencyProperty ToBoundsProperty =
            DependencyProperty.RegisterAttached("ToBounds", typeof(bool),
                                                typeof(ClipBoundsControl), new PropertyMetadata(false, OnToBoundsPropertyChanged));


        private static void OnToBoundsPropertyChanged(DependencyObject d,
                                                      DependencyPropertyChangedEventArgs e)
        {
            var fe = d as FrameworkElement;
            if (fe != null)
            {
                ClipToBounds(fe);

                // whenever the element which this property is attached to is loaded
                // or re-sizes, we need to update its clipping geometry
                fe.Loaded += FeLoaded;
                fe.SizeChanged += FeSizeChanged;

            }
        }

        /// <summary>
        /// Creates a rectangular clipping geometry which matches the geometry of the
        /// passed element
        /// </summary>
        private static void ClipToBounds(FrameworkElement fe)
        {
            if (GetToBounds(fe))
            {
                fe.Clip = new RectangleGeometry
                              {
                                  Rect = new Rect(0, 0, fe.ActualWidth, fe.ActualHeight)
                              };
            }
            else
            {
                fe.Clip = null;
            }
        }

        static void FeSizeChanged(object sender, SizeChangedEventArgs e)
        {
            ClipToBounds(sender as FrameworkElement);
        }

        static void FeLoaded(object sender, RoutedEventArgs e)
        {
            ClipToBounds(sender as FrameworkElement);
        }
    }
}